package demo.aspect.redis;

import demo.utils.SerializeUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

@Aspect
public class JedisAspect2 {

    public static final String UTF8 = "UTF-8";

    //pointcut JedisExecuteTime():call(* redis.clients.jedis.BinaryClient.*(..,*));
//    pointcut JedisExecuteTime():call(* redis.clients.jedis.Jedis.*(..,*));

    @Pointcut("execution(* (redis.clients.jedis.BinaryJedis+).*(*,..))")
    public void jedisExecuteTime() {
    }

    @Around("jedisExecuteTime()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        Signature signature = pjp.getSignature();
        String signatureStr = signature.toString();

        long start = System.currentTimeMillis();
        System.out.println(String.format("----------start signature:%s , args: %s",
                signatureStr, Arrays.toString(args)));
        String key = getRedisKey(args);
        System.out.println("---------- key = " + key);
        Object retVal = pjp.proceed();
        long end = System.currentTimeMillis();
        System.out.println("---------- return = " + SerializeUtil.objectSize(retVal));
        System.out.println("----------cost = " + (end - start) + " ms");
        return retVal;
    }


    /**
     * 获取redis操作的key
     *
     * @param args
     * @return
     */
    private static String getRedisKey(Object[] args) {
        if (args == null || args.length == 0) {
            return null;
        }
        String key;
        Object arg0 = args[0];
        if (arg0 instanceof byte[]) {
            key = byte2Str((byte[]) arg0);
        } else if (arg0 instanceof byte[][]) {
            String[] strings = byte2StrArray((byte[][]) arg0);
            key = Arrays.toString(strings);
        } else if (arg0 instanceof String) {
            key = (String) arg0;
        } else {
            key = null;
        }
        if (key == null || key.length() <= 1024) {
            return key;
        }
        return key.substring(0, 1024);
    }

    /**
     * 字节数组转字符串
     *
     * @param bytes
     * @return
     */
    private static String[] byte2StrArray(byte[][] bytes) {
        if (bytes == null) {
            return null;
        }
        String[] result = new String[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            result[i] = byte2Str(bytes[i]);
        }
        return result;
    }

    /**
     * 字节数组转字符串
     *
     * @param bytes
     * @return
     */
    private static String byte2Str(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            return new String(bytes, UTF8);
        } catch (UnsupportedEncodingException e) {
            return new String(bytes);
        }
    }
}
